package nku.csc660;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IMServer
{

	public static final int NUMCLIENTS = 5;
	Server server;
	SharedDataStructure sharedDataStructure;

	public IMServer(int maxUsers){
		try{
			server = new Server();
			sharedDataStructure = new SharedDataStructure(maxUsers);
		}
		catch(IOException e){
			System.out.println("Couldn't start server!");
			System.exit(1);
		}
	}

	public static void main(String... args) throws IOException
	{
		IMServer serverInstance = new IMServer(NUMCLIENTS);
		serverInstance.startListening();
	}

	public void startListening() throws IOException{
		while(true){
			Socket serviceSocket = server.waitForConnection();
			PrintWriter pw = server.openOutputStream(serviceSocket);
			BufferedReader br = server.openInputStream(serviceSocket);
			int i = sharedDataStructure.isThereRoom();
			System.out.println(i);
			br.readLine();
			if(i == -1){
				Server.sendMessage1(pw, "NO");
			}
			else{
				System.out.println("I was here... ");
				sharedDataStructure.addToDataStructure(i, serviceSocket, pw, br);
				new MessagesThread(i).start();
			}
		}
	}


    class  MessagesThread extends Thread
    {
    	public int id;

    	public MessagesThread(int id){
    		this.id = id;
    	}

        public void run()
        {
        	try {
        		System.out.println("I am here, run!");
				initlize();
    		} catch (IOException e) { System.exit(1);}
        	while(true){
        		try {
					String line = sharedDataStructure.bufferedReaders[id].readLine();


					boolean booleanLogOut = line.equals("@LOGOUT");
					if(booleanLogOut){
						sharedDataStructure.sendToSpecificClient(id, id, "Server is closing all connections!");
						sharedDataStructure.sendBrodcastMessage(id, sharedDataStructure.clientNames.get(id) + " is logging out!");
						sharedDataStructure.deleteFromDataStructure(id);
						break;
					}

					boolean booleanWho = line.equals("@WHO");
					if(booleanWho){
						sharedDataStructure.sendToSpecificClientWho(id);
						continue;
					}


					boolean booleanSend = line.equals("@SEND");
					LinkedList<String> tempList = new LinkedList<String>();
					while(booleanSend)
					{
						line = sharedDataStructure.bufferedReaders[id].readLine();
						if(!line.equals("@DONE"))
						{
							tempList.add(line);
						}
						else{
							break;
						}
					}
					if(booleanSend){
						String[] tempArray = new String[tempList.size()];
						int i = 0;
						for(String temp: tempList){
							tempArray[i] = temp;
							i++;
						}
						sharedDataStructure.sendBrodcastMessage(id, tempArray);
						continue;
					}

					Pattern sendMessagePattern = Pattern.compile("@SEND.*");
					Matcher sendMessageMatcher = sendMessagePattern.matcher(line);
					boolean booleanSend1 = sendMessageMatcher.matches();
					LinkedList<String> tempList1 = new LinkedList<String>();
					String sendTo= "";
					int sendToId = -1;
					if(booleanSend1)
					{
						String[] tempArray = line.split(" ");
						sendTo = tempArray[1];
						for(int i: sharedDataStructure.clientNames.keySet()){
							if(sharedDataStructure.clientNames.get(i).equals(sendTo)){
								sendToId = i;
							}
						}
					}
					while(booleanSend1)
					{
						line = sharedDataStructure.bufferedReaders[id].readLine();
						if(!line.equals("@DONE"))
						{
							tempList1.add(line);
						}
						else{
							break;
						}
					}
					if(booleanSend1){
						String[] tempArray = new String[tempList.size()+1];
						int i = 0;
						for(String temp: tempList1){
							System.out.println(temp);
							tempArray[i] = temp;
							i++;
						}
						if(sendToId != -1){
							sharedDataStructure.sendToSpecificClient(id, sendToId, tempArray);
						}
						else{
							sharedDataStructure.sendToSpecificClient(id, id, "User Not Found!");
						}
						continue;
					}



        		} catch (IOException e) { System.exit(1);}
        	}
        }

		private void initlize() throws IOException {
			System.out.println("I am in the initlize");
			Server.sendMessage1(sharedDataStructure.printWriters[id], "YES");
			Server.sendMessage1(sharedDataStructure.printWriters[id], "What is your name?");
			String name = sharedDataStructure.bufferedReaders[id].readLine();
			sharedDataStructure.putName(id, name);
			sharedDataStructure.sendBrodcastMessage(id, name + " just joined the chat!");

		}
    }
}
